package com.jnevision.user.service;

import java.math.BigDecimal;
import java.time.LocalDate;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.api.R;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.jnevision.common.CommonQuery;
import com.jnevision.dept.model.Dept;
import com.jnevision.dept.service.DeptServiceImpl;
import com.jnevision.dict.model.Dict;
import com.jnevision.dict.service.DictServiceImpl;
import com.jnevision.salary.mapper.SalaryMapper;
import com.jnevision.salary.model.Salary;
import com.jnevision.user.mapper.UserMapper;
import com.jnevision.user.model.User;
import com.jnevision.user.model.UserStatistics;
import com.jnevision.user.model.UserVO;
import com.jnevision.userdept.mapper.UserDeptMapper;
import com.jnevision.userdept.model.UserDept;
import com.jnevision.userrole.mapper.UserRoleMapper;
import com.jnevision.userrole.model.UserRole;
import com.jnevision.util.JsonMapper;

/**
 * <p>
 * 用户 服务实现类
 * </p>
 *
 * @author gavin
 * @since 2019-07-13
 */
@Service
public class UserServiceImpl extends ServiceImpl<UserMapper, User> {
    @Autowired
    private UserMapper userMapper;
    @Autowired
    private UserDeptMapper userDeptMapper;
    @Autowired
    private DeptServiceImpl deptServiceImpl;
    @Autowired
    private StringRedisTemplate redisTemplate;

    @Autowired
    private SalaryMapper salaryMapper;
    @Autowired
    private UserRoleMapper userRoleMapper;

    @Autowired
    private DictServiceImpl dictServiceImpl;

    /**
     * 根据部门获取部门内的用户
     * 
     * @param page
     * @param deptId
     * @param user
     * @return
     */
    public IPage<User> getUser(Page<User> page, int deptId, User user) {
        Dept dept = this.deptServiceImpl.getById(deptId);
        IPage<User> users = null;
        if (dept.getType() == 4) {
            /*
             * 拿到项目部的所有部门
             * 根据所有的部门获取用户为manager的人员
             */
            List<Dept> children = this.deptServiceImpl.getChildren(dept.getParentId());
            List<Integer> ids = children.stream().map(Dept::getId).collect(Collectors.toList());

            users = this.userMapper.getManagerUser(page, ids, user);
        } else {
            List<Dept> children = this.deptServiceImpl.getChildren(deptId);
            List<Integer> ids = children.stream().map(Dept::getId).collect(Collectors.toList());

            users = this.userMapper.getUser(page, ids, user);
        }

        users.getRecords().forEach(u -> {
            Dict one = this.dictServiceImpl.getOne(new QueryWrapper<Dict>().eq("type", "job").eq("value", u.getJob()));
            if (null != one) {
                u.setJob(one.getLabel());
                u.setPassword("");
            }
        });

        return users;
    }

    /**
     * 查询上级主管
     */
    public User getParentUser(String id) {
        // TODO 需要确定唯一性，不然的话就需要人为的从前端选择
        UserRole ur = this.userRoleMapper.selectOne(new QueryWrapper<UserRole>().eq("user_id", id));

        int deptId =
            this.userDeptMapper.selectOne(new QueryWrapper<UserDept>().eq("user_id", id).last("limit 1")).getDeptId();

        if (ur.getRoleId() == 4) {
            String userId = this.userDeptMapper.getCurrentDeptLeader(deptId);
            User user = this.userMapper.selectById(userId);
            if (user == null) {
                throw new RuntimeException("没有部门主管的审批");
            }
            return user;
        } else if (ur.getRoleId() == 1 || ur.getRoleId() == 6) {
            return this.userMapper.selectById(id);
        } else {
            int parentId = this.deptServiceImpl.getById(deptId).getParentId();

            String userId = this.userDeptMapper.getCurrentDeptLeader(parentId);
            User user = this.userMapper.selectById(userId);
            if (user == null) {
                throw new RuntimeException("没有部门主管的审批");
            }
            return user;
        }

        // int parentDeptId = this.deptMapper.selectById(deptId).getParentId();
        //
        // String userId =
        // this.userDeptMapper.selectOne(new QueryWrapper<UserDept>().eq("dept_id", parentDeptId)).getUserId();
        //
        // return this.userMapper.selectById(userId);
    }

    public String getProjectManagerByCurrentUser(String token) {
        Dept dept = this.deptServiceImpl.getProject(token);

        if (dept == null) {
            throw new RuntimeException("没有查询到当前用户所在项目的项目经理");
        }

        return this.userDeptMapper.getCurrentDeptLeader(dept.getId());
    }

    public List<UserVO> entryUser(String start, String end, int deptId) {
        return this.baseMapper.entryUser(start, end, deptId);
    }

    public List<UserVO> outUser(String start, String end, int deptId) {
        return this.baseMapper.outUser(start, end, deptId);
    }

    public User getLoginUser(String token) {
        User user = JsonMapper.nonDefaultMapper().fromJson(this.redisTemplate.boundValueOps(token).get(), User.class);
        return user;
    }

    public IPage<UserVO> pages(Page<UserVO> page, User user) {

        return this.baseMapper.pages(page, user);
    }

    public List<User> getDeptUser(int deptId) {
        return this.baseMapper.getDeptUser(deptId);
    }

    public R<List<Map<String, String>>> getGongling() {

        List<User> list = this.baseMapper.selectList(new QueryWrapper<User>().eq("is_signing", true));
        List<Map<String, String>> resultList = new ArrayList<>();

        int a = 0;
        int b = 0;
        int c = 0;
        int d = 0;
        int e = 0;

        Map<String, String> map = new HashMap<>();
        for (int i = 0; i < list.size(); i++) {

            LocalDate now = LocalDate.now();

            LocalDate entryTiem = LocalDate.parse(list.get(i).getEntryTime());

            long days = now.toEpochDay() - entryTiem.toEpochDay();

            long gongling = (days / 365);

            if (gongling == 0) {
                a += 1;
            } else if (gongling > 1 && gongling < 3) {
                b += 1;
            } else if (gongling > 3 && gongling < 5) {
                c += 1;
            } else if (gongling > 5 && gongling < 10) {
                d += 1;
            } else {
                e += 1;
            }
            map.put("1年以下", String.valueOf(a));
            map.put("1-3年", String.valueOf(b));
            map.put("3-5年", String.valueOf(c));
            map.put("5-10年", String.valueOf(d));
            map.put("10年以上", String.valueOf(e));
        }
        for (String key : map.keySet()) {
            Map<String, String> mapResult = new HashMap<>();
            mapResult.put("name", key);
            mapResult.put("value", map.get(key));
            resultList.add(mapResult);
        }

        return R.ok(resultList);
    }

    public List<UserStatistics> userStatistics(CommonQuery commonQuery) {

        List<UserStatistics> resultList = new ArrayList<>();

        List<Dept> list = this.deptServiceImpl.list(
            new QueryWrapper<Dept>().eq("type", 3).eq(null != commonQuery.getDeptId(), "id", commonQuery.getDeptId()));
        for (Dept dept : list) {
            List<UserDept> list2 =
                this.userDeptMapper.selectList(new QueryWrapper<UserDept>().eq("dept_id", dept.getId()));
            List<String> collect = list2.stream().map(UserDept::getUserId).collect(Collectors.toList());

            if (!CollectionUtils.isEmpty(collect)) {
                UserStatistics userStatistics = new UserStatistics();
                List<User> selectList2 = this.baseMapper.selectList(new QueryWrapper<User>().in("id", collect).eq("is_valid", true).between(
                    StringUtils.isNotEmpty(commonQuery.getStart()) && StringUtils.isNotEmpty(commonQuery.getEnd()),
                    "create_time", commonQuery.getStart(), commonQuery.getEnd()));
                
                List<User> selectList = this.baseMapper.selectList(new QueryWrapper<User>().in("id", collect).eq("is_valid", false).between(
                        StringUtils.isNotEmpty(commonQuery.getStart()) && StringUtils.isNotEmpty(commonQuery.getEnd()),
                        "create_time", commonQuery.getStart(), commonQuery.getEnd()));
                userStatistics.setDeptId(dept.getId());
                userStatistics.setDeptName(dept.getName());
                userStatistics.setTotal(selectList2.size());

                int entryNum = 0;
                int onTheJobNum = 0;
                BigDecimal salary = new BigDecimal(0);
                for (int i = 0; i < selectList2.size(); i++) {
                    if (selectList2.get(i).isValid() && selectList2.get(i).isSigning() && LocalDate.now().toEpochDay()-LocalDate.parse(selectList2.get(i).getEntryTime()).toEpochDay()<31) {
                        entryNum += 1;
                    }
                    if (selectList2.get(i).isValid()&& LocalDate.now().toEpochDay()-LocalDate.parse(selectList2.get(i).getEntryTime()).toEpochDay()>31) {
                        onTheJobNum += 1;
                    }

                    Salary sa = this.salaryMapper
                        .selectOne(new QueryWrapper<Salary>().eq("user_id", selectList2.get(i).getId()));

                    if (null != sa) {
                        BigDecimal baozhang =
                            new BigDecimal(StringUtils.isEmpty(sa.getBaozhang()) ? "0" : sa.getBaozhang());
                        BigDecimal gangwei =
                            new BigDecimal(StringUtils.isEmpty(sa.getGangwei()) ? "0" : sa.getGangwei());
                        BigDecimal gongling =
                            new BigDecimal(StringUtils.isEmpty(sa.getGongling()) ? "0" : sa.getGongling());
                        BigDecimal jiabanfei =
                            new BigDecimal(StringUtils.isEmpty(sa.getJiabanfei()) ? "0" : sa.getJiabanfei());

                        salary = salary.add(baozhang).add(gangwei).add(gongling).add(jiabanfei);
                    }
                }
                userStatistics.setEntryNum(entryNum);
                userStatistics.setOnTheJobNum(onTheJobNum);
                userStatistics.setQuitNum(selectList.size());
                userStatistics.setSalary(salary.intValue());
                resultList.add(userStatistics);
            }

        }

        return resultList;
    }

    public Integer countLeader(Integer id) {
        return this.baseMapper.countLeader(id);
    }

    public Integer countManager(Integer id) {
        return this.baseMapper.countManager(id);
    }
}
